package cn.italkcloud.cph.service.impl;

import cn.italkcloud.cph.constants.enums.vos.CustomerTypeEnum;
import cn.italkcloud.cph.entity.VosCustomer;
import cn.italkcloud.cph.entity.dto.vos.CustomerDetailDTO;
import cn.italkcloud.cph.entity.wrapper.VosWrapper;
import cn.italkcloud.cph.helper.VosHelper;
import cn.italkcloud.cph.mapper.VosCustomerMapper;
import cn.italkcloud.cph.service.IVosCustomerService;
import cn.italkcloud.cph.utils.SqlUtil;
import cn.italkcloud.cph.utils.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * <p>
 * VOS账户 服务实现类
 * </p>
 *
 * @author dominate
 * @since 2024-07-05
 */
@Service
public class VosCustomerServiceImpl extends ServiceImpl<VosCustomerMapper, VosCustomer> implements IVosCustomerService {

    private static VosCustomer createCustomerByVos(int serverId, String apiUrl, String vosAccount) {
        CustomerDetailDTO customerDetail = VosHelper.getCustomerDetail(apiUrl, vosAccount);
        VosCustomer vosCustomer = VosWrapper.builder().entityDTO(customerDetail);
        vosCustomer.setServerId(serverId);
        vosCustomer.setAccountId(0);
        vosCustomer.setIsDel(false);
        return vosCustomer;
    }

    @Override
    public boolean isOwner(int accountId, int id) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getAccountId, accountId)
                .eq(VosCustomer::getId, id);
        return count(query) > 0;
    }

    @Override
    public VosCustomer getByVosAccount(int serverId, String apiUrl, String vosAccount) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getVosAccount, vosAccount)
                .eq(VosCustomer::getServerId, serverId)
                .eq(VosCustomer::getIsDel, false)
                .last(SqlUtil.limitOne());
        VosCustomer customer = getOne(query);
        if (null == customer) {
            customer = createCustomerByVos(serverId, apiUrl, vosAccount);
            save(customer);
        }
        return customer;
    }

    @Override
    public List<VosCustomer> query(int accountId, int serverId, String vosKey, CustomerTypeEnum customerType) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(accountId != 0, VosCustomer::getAccountId, accountId)
                .eq(serverId != 0, VosCustomer::getServerId, serverId)
                .eq(CustomerTypeEnum.ALL != customerType, VosCustomer::getType, customerType.getCode())
                .and(StringUtil.isNotEmpty(vosKey), q -> q.or().like(VosCustomer::getVosName, vosKey)
                        .or().like(VosCustomer::getVosAccount, vosKey))
                .gt(VosCustomer::getAccountId, 0)
                .eq(VosCustomer::getIsDel, false);
        return list(query);
    }

    @Override
    public List<VosCustomer> getByAccountId(int accountId) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getAccountId, accountId)
                .eq(VosCustomer::getIsDel, false);
        return list(query);
    }


    @Override
    public int findByVosAccount(int serverId, String vosAccount) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getVosAccount, vosAccount)
                .eq(VosCustomer::getServerId, serverId)
                .eq(VosCustomer::getIsDel, false)
                .select(VosCustomer::getId).last(SqlUtil.limitOne());
        VosCustomer vosCustomer = getOne(query);
        if (null == vosCustomer) {
            return 0;
        }
        return vosCustomer.getId();
    }

    @Override
    public List<Integer> findByAccountId(int serverId, int accountId) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getAccountId, accountId)
                .eq(VosCustomer::getServerId, serverId)
                .select(VosCustomer::getId);
        List<VosCustomer> customerList = list(query);
        List<Integer> idList = new ArrayList<>();
        for (VosCustomer customer : customerList) {
            idList.add(customer.getId());
        }
        return idList;
    }

    @Override
    public List<VosCustomer> getValidList(int serverId) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getServerId, serverId)
                .eq(VosCustomer::getIsDel, false)
                .gt(VosCustomer::getAccountId, 0);
        return list(query);
    }

    @Override
    public Map<Integer, String> getVosAccountMap(Collection<Integer> idCollection) {
        if (CollectionUtils.isEmpty(idCollection)) {
            return Collections.emptyMap();
        }
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().in(VosCustomer::getId, idCollection);
        List<VosCustomer> list = list(query);
        Map<Integer, String> vosAccountMap = new HashMap<>(list.size());
        for (VosCustomer vosCustomer : list) {
            vosAccountMap.put(vosCustomer.getId(), vosCustomer.getVosAccount());
        }
        return vosAccountMap;
    }

    @Override
    public List<VosCustomer> getListByIds(Collection<Integer> idCollection) {
        if (CollectionUtils.isEmpty(idCollection)) {
            return Collections.emptyList();
        }
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().in(VosCustomer::getId, idCollection);
        return list(query);
    }

    @Override
    public boolean unbind(int id) {
        VosCustomer update = new VosCustomer()
                .setId(id)
                .setAccountId(0);
        return updateById(update);
    }

    @Override
    public boolean hasCustomer(int serverId) {
        QueryWrapper<VosCustomer> query = new QueryWrapper<>();
        query.lambda().eq(VosCustomer::getServerId, serverId);
        return count(query) > 0;
    }


}
